package n50_atomic;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicInteger;

import static utils.Sleeper.sleep;

/**
 * @author fu
 * @date 2022-02-18 22:58
 * 概要：
 * ---------------------------------------------------------------
 * |                                                              |
 * |        CAS 来 实现锁的 原理     【注意不能用于生产实践】          |
 * |                                                             |
 * |=============================================================
 */
@Slf4j(topic = "c.T10")
public class T10_源码之LongAdder_CAS模拟实现锁的原理 {

    public static void main(String[] args) {

        LockCas lock = new LockCas();
        new Thread(() -> {
            log.debug("begin...");
            lock.lock();
            try {
                log.debug("lock...");
                sleep(1);
            } finally {
                lock.unlock();
            }
        }).start();

        new Thread(() -> {
            log.debug("begin...");
            lock.lock();
            try {
                log.debug("lock...");
            } finally {
                lock.unlock();
            }
        }).start();
/*

        23:03:04.672 [Thread-0] c.T10 - begin...
        23:03:04.672 [Thread-1] c.T10 - begin...
        23:03:04.674 [Thread-0] c.T10 - lock...
        23:03:05.683 [Thread-0] c.LockCas - unlock...
        23:03:05.683 [Thread-1] c.T10 - lock...
        23:03:05.683 [Thread-1] c.LockCas - unlock...
*/

    }
}

// 不要用于实践！！！
@Slf4j(topic = "c.LockCas")
class LockCas {
    private AtomicInteger state = new AtomicInteger(0);
    // 死循环 来 模拟 [加锁]
    public void lock() {
        while (true) {
            if (state.compareAndSet(0, 1)) {
                log.debug("匹配 并更改成功");
                break;
            }
        }
    }
    // 同一线程 设置0匹配成功 模拟 [解锁]
    public void unlock() {
        log.debug("unlock...");
        state.set(0);
    }
}